#define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <sys/syscall.h> #include <stdlib.h> #include <limits.h> #include <errno.h> int main(int argc, char ** argv) { int fd[2]; int len,slen,len_out,slen_out; pipe(fd); int f=open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644); len=tee(STDIN_FILENO,fd[1],INT_MAX,SPLICE_F_MOVE); while (len > 0) { slen = splice(fd[0], NULL, f, NULL, len, SPLICE_F_MOVE); len -= slen; if(slen==0) break; } len_out = tee(STDIN_FILENO,fd[1],INT_MAX,SPLICE_F_MOVE); while (len_out > 0) { slen_out = splice(fd[0], NULL, STDOUT_FILENO, NULL, len_out, SPLICE_F_MOVE); len_out -= slen_out; if(slen_out==0) break; } close(fd[1]); close(fd[0]); close(f); return 0; } Cuando ejecuto mi programa con una tubería ex: cat test.txt| ./a.out result.txt El contenido de test.txt va a result.txt
Pero con el otro método, ej: ./a.out result.txt <test.txt no pasa nada. ¿No se supone que debe actuar de la misma manera?
Además, cuando STDOUT_FILENO , nunca se imprime en la salida estándar y no entiendo por qué.
Gracias por tu ayuda
Los dos métodos no son equivalentes:
cat in.txt | en realidad creará una pipe para alimentar su programa< in.txt simplemente open el archivo dado y lo servirá como fd 0 En el segundo caso, tee devuelve -1 y perror se queja de un argumento inválido.
Puede verificar la naturaleza de fd 0 usando fstat y verificando el valor de st_mode :
struct stat statbuf; fstat(STDIN_FILENO, &statbuf); if (statbuf.st_mode & S_IFREG) printf("regular file"); if (statbuf.st_mode & S_IFIFO) printf("pipe");